#!/usr/bin/env python

    ##########################################################################
    ##(c) 2008 Bastian Damman                                               ##
    ##                                                                      ##
    ##This file is part of Kaboom-O-rama.                                   ##
    ##                                                                      ##
    ##Kaboom-O-rama is free software: you can redistribute it and/or modify ##
    ##it under the terms of the GNU General Public License as published by  ##
    ##the Free Software Foundation, either version 3 of the License, or     ##
    ##(at your option) any later version.                                   ##
    ##                                                                      ##
    ##Kaboom-O-rama is distributed in the hope that it will be useful,      ##
    ##but WITHOUT ANY WARRANTY; without even the implied warranty of        ##
    ##MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         ##
    ##GNU General Public License for more details.                          ##
    ##                                                                      ##
    ##You should have received a copy of the GNU General Public License     ##
    ##along with Kaboom-O-rama.  If not, see <http://www.gnu.org/licenses/>.##
    ##########################################################################

from pygame import *
from Main import screenWidth
from Parser import NORMAL_KEYS, ALMOST_NORMAL_KEYS, SPECIAL_KEYS
import Parser as parser
from KeyboardInterpreter import get_key
from TerminalFunctions import TerminalFunctions

class Terminal:
    def __init__(self, parent, fps):
        self.parent = parent
        self.max_height = 196
        self.terminal_alpha = 128
        self.text_size = 16
        self.text_color = (0, 255, 128)
        self.back_color = (0, 0, 0)
        self.border_color = self.text_color
        
        self.terminal_surf = Surface((screenWidth, self.max_height))
        self.terminal_surf.fill(self.back_color)
        self.terminal_surf.set_alpha(self.terminal_alpha)
        
        self.font = font.SysFont(font.get_default_font(), self.text_size)
        self.text_height = self.font.get_height()      
        self.text = [] #per string
        self.text.append("")
        self.max_lines_disp = self.max_height / self.text_height
            
        self.blink_char = "_"     
        self.blink_speed = fps / 4
        self.blink_timer = 0
        self.blinking = True # _ :visible
        
        self.scrol_index = 0
        
        self.show = False
        self.hide = False
        self.visible = False
        self.show_speed = 5
        self.hide_speed = 5
        self.y = -1
        
        self.functions = []
        self.init_t_functions()
        
        self.Show()
    
    
    
    def Show(self):
        self.hide = False
        self.show = True
    
    def Hide(self):
        self.hide = True
        self.show = False
    
    def init_t_functions(self):
        tf = TerminalFunctions(self.parent)
        
        #-------GLOBAL-------#
        self.add_t_function("exit", 0, tf.t_exit)
        
        #-------GRID------#
        self.add_t_function("grid.set_width", 1, tf.grid_set_width)
        self.add_t_function("grid.set_height", 1, tf.grid_set_height)
        self.add_t_function("grid.add_xcells", 1, tf.grid_add_xcells)
        self.add_t_function("grid.add_ycells", 1, tf.grid_add_ycells)
        self.add_t_function("grid.get_width", 0, tf.grid_get_width)
        self.add_t_function("grid.get_height", 0, tf.grid_get_height)
        self.add_t_function("grid.get_cel_size", 0, tf.grid_get_cel_size)
        
        #-------TOOL-------#
        self.add_t_function("tool.set_tool", 1, tf.tool_set_tool)
        self.add_t_function("tool.set_flag", 2, tf.tool_set_flag)
        self.add_t_function("tool.get_flags", 0, tf.tool_get_flags)
    
    def add_t_function(self, name, arguments, do):
        self.functions.append([name, arguments, do])
    
    def find_t_function(self, function):
        for i in range(len(self.functions)):
            if function.startswith(self.functions[i][0]):
                return i
        return -1
            
    def do_t_function(self, index, function):
        f = self.functions[index]
        if f[1] > 0:
            ret = None
            t_arg = function[len(f[0])+1: -1]
            t_arg.replace(" ", "")
            t_arg = t_arg.split(",")
            try:
                arg = []
                for a in t_arg:
                    arg.append(int(a))
                if f[1] == 1: ret = f[2](arg[0])
                elif f[1] == 2: ret = f[2](arg[0], arg[1])
                elif f[1] == 3: ret = f[2](arg[0], arg[1], arg[2])
                elif f[1] == 4: ret = f[2](arg[0], arg[1], arg[2], arg[3])
            except(TypeError, ValueError):
                return "  >>Syntax Error"
            else:
                return "  >>DONE: output: %s" % str(ret)
        else:
            ret = f[2]()
            return "  >>DONE: output: %s" % str(ret)
            
    
    def execute(self, properties):        
        index = self.find_t_function(self.text[-1])
        if index == -1:
            self.text.append('  >>ERROR UNKOWN COMMAND: "' + self.text[-1]+'"')
        else:
            ret = self.do_t_function(index, self.text[-1])
            self.text.append(ret)
        
        self.text.append("")
        self.scrol_index = len(self.text) - 1
    
    def handle_input(self, k, properties):
        if k == K_RETURN:
            self.execute(properties)
            return None
        elif k == K_SPACE:
            return " "
        elif k == K_BACKSPACE:
            self.text[-1] = self.text[-1][:-1]
            return None
        elif k == K_UP:
            self.scrol_index -= 2
            if self.scrol_index < 0:
                self.scrol_index = 0
            self.text[-1] = self.text[self.scrol_index]
        elif k == K_DOWN:
            self.scrol_index += 2
            if self.scrol_index >= len(self.text) - 1:
                self.scrol_index = len(self.text) - 1
                self.text[-1] = ""
            self.text[-1] = self.text[self.scrol_index]
        else:
            return None
        
    def move(self):
        if self.show:
            if len(self.text) < self.max_lines_disp:
                yto = len(self.text) * self.text_height
            else:
                yto = self.max_height
        elif self.hide:
            yto = -1
        
        if yto < self.y - self.hide_speed:
            self.y -= self.hide_speed
        elif yto > self.y + self.show_speed:
            self.y += self.show_speed
        else:
            self.y = yto
    
    def update(self, events, properties):
        k = get_key(properties.azerty, events)
        if k != None:
            self.text[-1] += k
        for e in events:
            if e.type == KEYDOWN:                    
                if e.key in SPECIAL_KEYS:
                    out = self.handle_input(e.key, properties)
                    if out != None:
                        self.text[-1] += out
                
                else:
                    k = key.name(e.key)
                    if k == "`":
                        if self.show:
                            self.Hide()
                        else:
                            self.Show()
                
        
        self.move()            
        if self.hide:
           if self.y <= -1:
            self.visible = False
        elif self.show:
            self.visible = True
            #show
            #self.show = True #niet op false zetten!
            
        ##---------blinker---------##
        self.blink_timer += 1
        if self.blink_timer >= self.blink_speed:
            self.blinking = not self.blinking
            self.blink_timer = 0
    
    def draw(self, screen):
        #if self.visible:
            text_draw = [] #set text to draw here
            self.terminal_surf.fill(self.back_color)
            
            start = len(self.text) - self.max_lines_disp
            if start < 0: start = 0
            for t in range(start, len(self.text)):
                text_draw.append(self.text[t])
            text_draw.reverse()
            
            if self.blinking:
                text_draw[0] += self.blink_char
            
            y = self.max_height
            for t in text_draw:
                text_surf = self.font.render(t, 1, self.text_color, self.back_color)
                self.terminal_surf.blit(text_surf, (8, y - text_surf.get_height()))
                y -= text_surf.get_height()
            
            
            
            screen.blit(self.terminal_surf, (0, self.y - self.max_height))
            
            